package com.example.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.annotation.Log;
import com.example.common.result.Result;
import com.example.entity.activiti.ApprovalVo;
import com.example.entity.activiti.FlowInfo;
import com.example.entity.dto.TaskDto;
import com.example.entity.dto.TaskInit;
import com.example.entity.dto.TaskPageDto;
import com.example.entity.dto.User.MyUser;
import com.example.entity.hz.HttpResult;
import com.example.entity.hz.ShenHe;
import com.example.entity.vo.CopmgVo;
import com.example.entity.yifei.Coptc;
import com.example.service.TaskInitService;
import com.example.service.impl.ActFlowCommService;
import com.example.service.impl.FlowService;
import com.example.untils.HttpClientUtil;
import com.example.untils.SecurityUtils;
import com.example.untils.StringUtils;
import com.example.untils.TimeUtils;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 流程管理
 */
@RestController
@RequestMapping("/api/flow")
@Api(tags = "流程相关接口")
@Slf4j
public class FlowController {
    @Autowired
    private FlowService flowService;
    @Autowired
    private ActFlowCommService actFlowCommService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskInitService taskInitService;
    /**
     * 查询所有流程 未部署和已部署，备用接口，暂时不用
     *
     * @return
     */
    @GetMapping("/findAll")
    @ApiOperation("查询所有流程定义接口，备用")
    public List<FlowInfo> findAllFlow() {
        return flowService.findAllFlow();
    }

    /**
     * 部署流程
     *备用接口，暂不使用
     * @param request
     * @return 0-部署失败  1- 部署成功  2- 已经部署过
     */
    @PutMapping("/deployment/{id}")
    @ApiOperation("部署流程，备用")
    public Integer deployment(HttpServletRequest request, @PathVariable(name = "id") Long id) {
        FlowInfo flowInfo = flowService.findOneFlow(id);
        if (flowInfo.getState() == 0) {
            return 2;
        }
        actFlowCommService.saveNewDeploy(flowInfo);
        return flowService.updateDeployState(id);
    }

    @GetMapping("/getTaskInit")
    @ApiOperation("获取审核流程用户自定义信息")
    public Result getTaskInit() {
        List<Map> mapList = actFlowCommService.getTaskInit();
        return Result.success(mapList);
    }

    @PostMapping("/completeTasks")
    @ApiOperation("批量完成任务")
    @Transactional
    public Result copleteTasks(@RequestParam String remark, @RequestParam List<String> taskIds, @RequestParam(required = false) String advice) {
        MyUser loginUser = SecurityUtils.getLoginUser();
        String userName = loginUser.getUsername();
        log.info("username:{}", userName);
        log.info("remark={},taskId={},username={},意见={}", remark, taskIds, userName, advice);
        taskIds.forEach(taskId -> {
            flowService.completeTask(remark, userName, taskId, advice);
        });
        return Result.success("批量完成任务成功！");
    }

    @PostMapping("/completeTaskList")
    @ApiOperation("批量执行完成任务")
    @Transactional
    public Result copleteTasks(@RequestBody List<TaskDto> taskDto) {
        MyUser loginUser = SecurityUtils.getLoginUser();
        String userName = loginUser.getUsername();
        log.info("username:{}", userName);
//        log.info("remark={},taskId={},username={},意见={}", remark, taskIds, userName, advice);
//        taskDto.forEach(arr -> {
        // 取list中相同品号的创建时间最新数据
        Map<String, TaskDto> map = taskDto.stream()
                .collect(Collectors.toMap(TaskDto::getTaskId, Function.identity(), (o1, o2) -> o1));
        List<TaskDto> resultList = new ArrayList<>(map.values());
        resultList.forEach(arr -> {
            flowService.completeTask(arr.getRemark(), userName, arr.getTaskId(), arr.getAdvice());
        });
//        });
        return Result.success("批量完成任务成功！");
    }

    @GetMapping("/getTaskInits")
    @ApiOperation("获取审核流程用户自定义信息 8月1日")
    public Result getTaskInits() {
        List<Map> mapList = actFlowCommService.getTaskInits();
        return Result.success(mapList);
    }

    @ApiOperation("自定义审核流程用户信息")
    @PostMapping("/taskInit")
    public Result taskInit(@RequestBody TaskInit taskInit) {
        boolean b = taskInitService.saveOrUpdateTaskInit(taskInit);
        if (b)
            return Result.success("任务初始化成功");
        else
            return Result.error("初始化失败");
    }

    @ApiOperation("自定义审核流程用户信息 8月1日")
    @PostMapping("/taskInits")
    public Result taskInits(@RequestBody TaskInit taskInit) {
        boolean b = taskInitService.saveOrUpdateTaskInits(taskInit);
        if (b)
            return Result.success("任务初始化成功");
        else
            return Result.error("初始化失败");
    }

    @Log("上报审核")
    @ApiOperation("上报审核")
    @PostMapping("/report")
    public Result report(
            @RequestParam String TC001,@RequestParam String TC002,@RequestParam String formKey,@RequestParam String leader
    ) {
        log.info("请购进入审批流程");
        MyUser loginUser = SecurityUtils.getLoginUser();
        String userName = loginUser.getUsername();
        if (StringUtils.isEmpty(TC001) || StringUtils.isEmpty(TC002)) {
            Result.error("单别或单号为空");
        }
        if (StringUtils.isEmpty(userName)){
            Result.error("用户名为空");
        }
        String beanName = formKey + "ServiceImpl";
//关联业务 bussinessKey
        String bussinessKey = formKey + ":" + TC001 + ":" + TC002;
        String id = TC001 +":"+ TC002;
        Boolean b=actFlowCommService.isOnly(bussinessKey,formKey);
        ProcessInstance processInstance;
        if (b){
            processInstance= actFlowCommService.startProcess(formKey, beanName, bussinessKey, id, userName, leader);
        }
        else {
            return Result.error("有相同单据正在审核！");
        }
        //获取流程实例id
        String processInstanceId = processInstance.getId();
        List<Task> taskList = actFlowCommService.myTaskList(userName);
        if (!CollectionUtils.isEmpty(taskList)) {
            for (Task task : taskList) {
                if (task.getAssignee().equals(userName) &&
                        task.getProcessInstanceId().equals(processInstanceId)) {
                    log.info("ProcessInstanceId is {}", task.getProcessInstanceId());
                    log.info("taskid is {}",task.getId());
                    actFlowCommService.completeProcess("同意", userName, task.getId(),"");
                }
            }
        }
        else {
            return Result.error("空任务！");
        }
        return Result.success("上报审核成功");
    }
    /**
     * 当前用户所有流程实例分页
     *在用
     * @param current 当前页码
     * @param size 页大小
     * @return
     */
    @PostMapping("/allInstance")
    @ApiOperation("当前用户流程实例分页")
    public Result allInstance(@RequestParam(defaultValue = "0") int current,
                              @RequestParam(defaultValue = "10") int size) {
        MyUser loginUser = SecurityUtils.getLoginUser();
        String userName = loginUser.getUsername();
        log.info("用户：{}",userName);
        PageInfo pageInfo = actFlowCommService.allProcessIns(userName, current, size);
        return Result.success(pageInfo);
    }

    @PostMapping("/allHisInstace")
    @ApiOperation("当前用户所有历史实例")
    public Result allHisInstace(@RequestParam(defaultValue = "0") int current,
                                @RequestParam(defaultValue = "10") int size) {
        MyUser loginUser = SecurityUtils.getLoginUser();
        String userName = loginUser.getUsername();
        log.info("用户：{}",userName);
        PageInfo pageInfo=actFlowCommService.allHisProcessIns(userName, current, size);
        return Result.success(pageInfo);
    }

    @ApiOperation("挂起申请流程")
    @PostMapping("/hangup")
    public Result hangup(@RequestParam String processInstanceId) {
        log.info("调用了挂起流程接口");
        runtimeService.suspendProcessInstanceById(processInstanceId);
        return Result.success("挂起成功");
    }

    @ApiOperation("激活申请流程")
    @PostMapping("/activi")
    public Result activi(@RequestParam String processInstanceId) {
        log.info("调用了激活流程接口");
        runtimeService.activateProcessInstanceById(processInstanceId);
        return Result.success("激活流程实例成功");
    }

    /**
     * 查询用户任务分页
     *掌上易飞接口
     * @param
     * @return
     */
    /*@GetMapping("/findUserTask")
    public List<Map<String, Object>> findUserTask(HttpServletRequest request) {
        Long userId = (Long) request.getSession().getAttribute("userid");
        return flowService.findUserTask(userId);
    }*/
    @PostMapping("/findUserTask")
    @ApiOperation("当前用户任务")
    public Result<Map<String, ApprovalVo>> findUserTask(@RequestBody TaskPageDto dto) {
        MyUser loginUser = SecurityUtils.getLoginUser();
        if(loginUser==null){
            return Result.error("没有登录信息,请重新登录");
        }
        String userName = loginUser.getUsername();
        log.info("username:{}",userName);
        System.out.printf("当前页=" + dto.getCurrent() + "页大小=" + dto.getSize() + "用户名=" + userName + "formkey=" + dto.getFormKey());
        return flowService.findUserTask(dto.getCurrent(), dto.getSize(), userName,dto.getFormKey(),dto.getDateAfter(),
                dto.getDateBefore(), dto.getBusinessKey(), dto.getApplicant());
    }

    @PostMapping("/findGroupTask")
    @ApiOperation("当前用户的组任务")
    public Result<PageInfo> findGroupTask(@RequestParam(defaultValue = "0") int current,
                                          @RequestParam(defaultValue = "10") int size, @RequestParam String formKey) {
        MyUser loginUser = SecurityUtils.getLoginUser();
        String userName = loginUser.getUsername();
        PageInfo groupTask = flowService.findGroupTask(current, size, userName, formKey);
        return Result.success(groupTask);
    }

    @PostMapping("/claimTask")
    @ApiOperation("拾取任务")
    public Result claimTask(@RequestParam String taskId) {
        MyUser loginUser = SecurityUtils.getLoginUser();
        String userName = loginUser.getUsername();
        System.out.printf("任务id：" + taskId + "。。。用户名" + userName);
        boolean b = flowService.claimTask(taskId, userName);
        if (b) {
            return Result.success();
        }
        return Result.error("拾取任务失败！");
    }

    @PostMapping("/returnTask")
    @ApiOperation("归还组任务")
    public Result returnTask(@RequestParam String taskId) {
        MyUser loginUser = SecurityUtils.getLoginUser();
        String userName = loginUser.getUsername();
        System.out.printf("任务id：" + taskId + "。。。用户名" + userName);
        boolean b = flowService.returnTask(taskId, userName);
        if (b) {
            return Result.success();
        }
        return Result.error("归还任务失败!");
    }

    /**
     * 查询任务的详情信息
     * 掌上易飞接口
     * @param taskID 任务id
     * @return
     */
   /* @PostMapping("/findTaskInfo")
    @ApiOperation("查询任务详情信息")
    public Result<Object> findTaskInfo(@RequestParam String taskID) {
        Object taskInfo = flowService.findTaskInfo(taskID);
        return Result.success(taskInfo);
    }*/

    /**
     * 完成任务
     *备用
     *
     */
    @PostMapping("/completeTask")
    @ApiOperation("完成当前任务")
    public Result completeTask(@RequestParam String remark, @RequestParam String taskId, @RequestParam(required = false) String advice) {
        MyUser loginUser = SecurityUtils.getLoginUser();
        String userName = loginUser.getUsername();
        log.info("remark={},taskId={},username={},意见={}", remark, taskId, userName, advice);
        flowService.completeTask(remark, userName, taskId, advice);
        return Result.success();
    }

    /**
     * 查询当前用户历史任务
     * @return
     */
    @PostMapping("/findFlowTask")
    @ApiOperation("当前用户历史任务")
    public Result<PageInfo> findFlowTask(@RequestBody TaskPageDto dto){
        MyUser loginUser = SecurityUtils.getLoginUser();
        if (loginUser==null){
            return Result.error("用户没有登录,请重新登录");
        }
        String userName = loginUser.getUsername();
        PageInfo pageInfo=flowService.findUserHisTask(dto.getCurrent(), dto.getSize(),userName,dto.getFormKey(),dto.getDateAfter(),
                dto.getDateBefore(), dto.getBusinessKey(), dto.getApplicant());
        return Result.success(pageInfo);
    }

    @ApiOperation("重新上报")
    @PostMapping("/secondreport")
    public Result report2(@RequestParam String TC001, @RequestParam String TC002,@RequestParam String formKey) {
        MyUser loginUser = SecurityUtils.getLoginUser();
        String userName = loginUser.getUsername();
        if (StringUtils.isEmpty(TC001) || StringUtils.isEmpty(TC002)) {
            Result.error("单别或单号为空");
        }
        if (StringUtils.isEmpty(userName)) {
            Result.error("用户名为空");
        }
        String businessKey = formKey+":"+TC001+":"+TC002;
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(businessKey).active().singleResult();
        String result = (String) runtimeService.getVariable(processInstance.getId(), "result");
        if (!result.equals("驳回")){
            return Result.error("该单据对应的审批流程并未驳回！无法重新上报！");
        }
        String processInstanceId = processInstance.getId();
        log.info("processInstanceId is {}", processInstanceId);
        List<Task> taskList = actFlowCommService.myTaskList(userName);
        if (!CollectionUtils.isEmpty(taskList)) {
            for (Task task : taskList) {
                if (task.getAssignee().equals(userName) &&
                        task.getProcessInstanceId().equals(processInstanceId)) {
                    log.info("ProcessInstanceId is {}", task.getProcessInstanceId());
                    log.info("taskid is {}", task.getId());
                    actFlowCommService.completeProcess("同意", userName, task.getId(), "重新上报");
                }
            }
        } else {
            return Result.error("当前用户任务列表为空！");
        }
        return Result.success("重新上报采购单成功");
    }

    @Autowired
    private ApprovalController approvalController;
    @ApiOperation("撤销上报")
    @PostMapping("/shutDown")
    public Result shutDownReport(@RequestParam String processInstanceId, @RequestParam(defaultValue = "申请人取消") String reason) {
        log.info("调用了撤销流程接口");
        Execution execution = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).onlyChildExecutions().singleResult();
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        runtimeService.setVariable(execution.getId(),"result","撤销");
        runtimeService.deleteProcessInstance(processInstanceId, reason);
        String businessKey=processInstance.getBusinessKey();
        String[] split = businessKey.split(":");
        String id=split[1]+":"+split[2];
        Result result = approvalController.approvalCancel(id);
        if (result.getCode().equals("200")){
            return Result.success("取消上报成功");
        }
        return Result.error("撤销审批失败！");
    }
    /*@RequestMapping(value = "/getFlowImgByInstanceId")
    @ApiOperation(value = "获取流程实例跟踪", httpMethod = "POST" ,notes = "获取流程实例跟踪")
    public void getFlowImgByInstanceId(@RequestBody Map<String, Object> map, HttpServletResponse response) {
        // processInstanceId 流程实例id
        //actFlowCommService.getFlowImgByInstanceId(map.get("processInstanceId").toString(), response);
    }*/
}